<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue'
defineExpose({
  start,
  failure,
  success,
})
let timer: number | null = null
let progressRef = ref<HTMLDivElement>()
interface Props {
  height?: number
  successColor?: string
  failureColor?: string
  defaultColor?: string
}
interface State {
  outWidth: number
  realWidth: number
  visible: boolean
  color: string
}
const props = withDefaults(defineProps<Props>(), {
  height: 5,
  successColor: '#67C23A',
  failureColor: '#F56C6C',
  defaultColor: '#409EFF',
})
const state = reactive<State>({
  outWidth: 0,
  realWidth: 0,
  visible: false,
  color: props.defaultColor,
})
function start() {
  if (timer) {
    clearInterval(timer)
    timer = null
  }
  state.color = props.defaultColor
  state.realWidth = 0
  state.visible = true
  timer = setInterval(() => {
    state.realWidth += 1
    if (state.realWidth > 90 && state.visible) {
      if (timer) {
        clearInterval(timer)
        timer = null
      }
    }
  }, 100)
}
function success() {
  state.color = props.successColor
  state.realWidth = 100
  state.visible = false
}
function failure() {
  state.color = props.failureColor
  state.realWidth = 100
  state.visible = false
}
onMounted(() => {
  if (progressRef.value) {
    state.outWidth = progressRef?.value?.offsetWidth
  }
})
</script>
<template>
  <div class="progress-wrapper" ref="progressRef">
    <Transition name="fade">
      <div class="real-progress" :style="{ height: props.height + 'px', width: state.realWidth + '%', backgroundColor: state.color }"></div>
    </Transition>
  </div>
</template>
<style lang="scss" scoped>
.progress-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  .real-progress {
    position: absolute;
    top: 0;
    left: 0;
    width: 0px;
    transition: all 0.5s ease-in-out;
  }
}
.fade-enter-active,
.fade-leave-active {
  transition: all 0.3s ease-in-out;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
